/**
 * Software License, Version 1.0
 * 
 * Copyright 2003 The Trustees of Indiana University.  All rights reserved.
 * 
 *
 *Redistribution and use in source and binary forms, with or without 
 *modification, are permitted provided that the following conditions are met:
 *
 *1) All redistributions of source code must retain the above copyright notice,
 * the list of authors in the original source code, this list of conditions and
 * the disclaimer listed in this license;
 *2) All redistributions in binary form must reproduce the above copyright 
 * notice, this list of conditions and the disclaimer listed in this license in
 * the documentation and/or other materials provided with the distribution;
 *3) Any documentation included with all redistributions must include the 
 * following acknowledgement:
 *
 *"This product includes software developed by the Community Grids Lab. For 
 * further information contact the Community Grids Lab at 
 * http://communitygrids.iu.edu/."
 *
 * Alternatively, this acknowledgement may appear in the software itself, and 
 * wherever such third-party acknowledgments normally appear.
 * 
 *4) The name Indiana University or Community Grids Lab or NaradaBrokering, 
 * shall not be used to endorse or promote products derived from this software 
 * without prior written permission from Indiana University.  For written 
 * permission, please contact the Advanced Research and Technology Institute 
 * ("ARTI") at 351 West 10th Street, Indianapolis, Indiana 46202.
 *5) Products derived from this software may not be called NaradaBrokering, 
 * nor may Indiana University or Community Grids Lab or NaradaBrokering appear
 * in their name, without prior written permission of ARTI.
 * 
 *
 * Indiana University provides no reassurances that the source code provided 
 * does not infringe the patent or any other intellectual property rights of 
 * any other entity.  Indiana University disclaims any liability to any 
 * recipient for claims brought by any other entity based on infringement of 
 * intellectual property rights or otherwise.  
 *
 *LICENSEE UNDERSTANDS THAT SOFTWARE IS PROVIDED "AS IS" FOR WHICH NO 
 *WARRANTIES AS TO CAPABILITIES OR ACCURACY ARE MADE. INDIANA UNIVERSITY GIVES
 *NO WARRANTIES AND MAKES NO REPRESENTATION THAT SOFTWARE IS FREE OF 
 *INFRINGEMENT OF THIRD PARTY PATENT, COPYRIGHT, OR OTHER PROPRIETARY RIGHTS. 
 *INDIANA UNIVERSITY MAKES NO WARRANTIES THAT SOFTWARE IS FREE FROM "BUGS", 
 *"VIRUSES", "TROJAN HORSES", "TRAP DOORS", "WORMS", OR OTHER HARMFUL CODE.  
 *LICENSEE ASSUMES THE ENTIRE RISK AS TO THE PERFORMANCE OF SOFTWARE AND/OR 
 *ASSOCIATED MATERIALS, AND TO THE PERFORMANCE AND VALIDITY OF INFORMATION 
 *GENERATED USING SOFTWARE.
 */
package cgl.narada.jms;

import java.io.Serializable;

import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MapMessage;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.StreamMessage;
import javax.jms.TextMessage;
import javax.jms.TransactionRolledBackException;

/**
   This class implements the Session defined in the JMS specification.

   @author Shrideep Pallickara
   $Revision$
   $Date$
*/

public abstract class JmsSession implements Session {

  private MessageListener messageListener = null;

  private boolean stopped = true;
  private boolean closed = false; 
  
  /** Creates a <CODE>BytesMessage</CODE> object. A <CODE>BytesMessage</CODE> 
      object is used to send a message containing a stream of uninterpreted 
      bytes.
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public BytesMessage createBytesMessage() throws JMSException {
    return new JmsBytesMessage();
  }
  
  /** Creates a <CODE>MapMessage</CODE> object. A <CODE>MapMessage</CODE> 
      object is used to send a self-defining set of name-value pairs, where 
      names are <CODE>String</CODE> objects and values are primitive values 
      in the Java programming language.
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public MapMessage createMapMessage() throws JMSException {
    return new JmsMapMessage();
  }
  
  
  /** Creates a <CODE>Message</CODE> object. The <CODE>Message</CODE> 
      interface is the root interface of all JMS messages. A 
      <CODE>Message</CODE> object holds all the standard message header 
      information. It can be sent when a message containing only header 
      information is sufficient.
      
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public Message createMessage() throws JMSException {
    return new JmsMessage();
  }
  
  
  /** Creates an <CODE>ObjectMessage</CODE> object. An <CODE>ObjectMessage 
      </CODE> object is used to send a message that contains a serializable 
      Java object.
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public ObjectMessage createObjectMessage() throws JMSException {
    return new JmsObjectMessage();
  }
  
  /** Creates an initialized <CODE>ObjectMessage</CODE> object. An 
      <CODE>ObjectMessage</CODE> object is used 
      to send a message that contains a serializable Java object.
      
      @param object the object to use to initialize this message
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public ObjectMessage createObjectMessage(Serializable object) 
    throws JMSException {
    JmsObjectMessage jmsObjMessage = new JmsObjectMessage();
    jmsObjMessage.setObject(object);
    return jmsObjMessage;
  }
  
  
  /** Creates a <CODE>StreamMessage</CODE> object. A <CODE>StreamMessage 
      </CODE> object is used to send a  self-defining stream of primitive 
      values in the Java programming language.
      
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */
  
  public StreamMessage createStreamMessage() throws JMSException {
    return new JmsStreamMessage();
  }
  
  
  /** Creates a <CODE>TextMessage</CODE> object. A <CODE>TextMessage</CODE> 
      object is used to send a message containing a <CODE>String</CODE>
      object.
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  
  public TextMessage createTextMessage() throws JMSException { 
    return new JmsTextMessage();
  }
  
  /** Creates an initialized <CODE>TextMessage</CODE> object. A 
      <CODE>TextMessage</CODE> object is used to send 
      a message containing a <CODE>String</CODE>.
      @param text the string used to initialize this message
      @exception JMSException if the JMS provider fails to create this message
      due to some internal error.
  */ 
  public TextMessage createTextMessage(String text) throws JMSException {
    JmsTextMessage jmsTextMessage = new JmsTextMessage();
    jmsTextMessage.setText(text);
    return jmsTextMessage;
  }
  
  /** Indicates whether the session is in transacted mode.
      @return true if the session is in transacted mode
      @exception JMSException if the JMS provider fails to return the 
      transaction mode due to some internal error.
  */ 
  public boolean  getTransacted() throws JMSException {
    /** for now simply return false */
    return false;
  }
  
  
  /** Commits all messages done in this transaction and releases any locks
      currently held.
      @exception JMSException if the JMS provider fails to commit the
      transaction due to some internal error.
      @exception TransactionRolledBackException if the transaction
      is rolled back due to some internal error
      during commit.
      @exception javax.jms.IllegalStateException if the method is not called 
      by a transacted session.
  */
  public  void commit() throws JMSException {
    /** JMS-NI */
  }
  
  
  /** Rolls back any messages done in this transaction and releases any locks 
      currently held.
      @exception JMSException if the JMS provider fails to roll back the
      transaction due to some internal error.
      @exception javax.jms.IllegalStateException if the method is not called 
      by a  transacted session.
  */
  public void  rollback() throws JMSException {
    /** JMS-NI*/
  }
  
  
  /** 
      Closes the session.
      <P>Since a provider may allocate some resources on behalf of a session 
      outside the JVM, clients should close the resources when they are not 
      needed. Relying on garbage collection to eventually reclaim these 
      resources may not be timely enough.
      
      <P>There is no need to close the producers and consumers
      of a closed session. 
      <P> This call will block until a <CODE>receive</CODE> call or message 
      listener in progress has completed. A blocked message consumer
      <CODE>receive</CODE> call returns <CODE>null</CODE> when this session 
      is closed.
      <P>Closing a transacted session must roll back the transaction
      in progress.
      <P>This method is the only <CODE>Session</CODE> method that can 
      be called concurrently. 
      <P>Invoking any other <CODE>Session</CODE> method on a closed session 
      must throw a <CODE>JMSException.IllegalStateException</CODE>. Closing a 
      closed session must <I>not</I> throw an exception.
      
      @exception JMSException if the JMS provider fails to close the
      session due to some internal error.
  */
  public  void close() throws JMSException {
    /** JMS-NI*/
    if (closed) {
      /** No need to do anything further, simply return */
      return;
    }
    closed=true;
  }
  
  /** 
      Stops message delivery in this session, and restarts message delivery
      with the oldest unacknowledged message.
      <P>All consumers deliver messages in a serial order.
      Acknowledging a received message automatically acknowledges all 
      messages that have been delivered to the client.
      <P>Restarting a session causes it to take the following actions:
      <UL>
      <LI>Stop message delivery
      <LI>Mark all messages that might have been delivered but not 
      acknowledged as "redelivered"
      <LI>Restart the delivery sequence including all unacknowledged 
      messages that had been previously delivered. Redelivered messages
      do not have to be delivered in 
      exactly their original delivery order.
      </UL>
      
      @exception JMSException if the JMS provider fails to stop and restart
      message delivery due to some internal error.
      @exception javax.jms.IllegalStateException if the method is called by a 
      transacted session.
  */ 
  public void recover() throws JMSException {
    /** JMS-NI Need to implement this feature */
    
  }
  
  
  /** Returns the session's distinguished message listener (optional).
      @return the message listener associated with this session
      @exception JMSException if the JMS provider fails to get the message 
      listener due to an internal error.
  */
  public MessageListener getMessageListener() throws JMSException {
    if (messageListener == null)
      throw new JMSException("The Message Listener is NULL");
    
    return messageListener;
  }
  
  /** Sets the session's distinguished message listener (optional).
      <P>When the distinguished message listener is set, no other form of 
      message receipt in the session can be used; however, all forms of 
      sending messages are still supported.
      <P>This is an expert facility not used by regular JMS clients.
      
      @param listener the message listener to associate with this session
      @exception JMSException if the JMS provider fails to set the message 
      listener due to an internal error.
  */
  public void setMessageListener(MessageListener listener) 
    throws JMSException {
    if (listener == null)
      throw new JMSException("Trying to set a NULL message listener ");
    
    messageListener = listener;
  }
  
  /**
     Optional operation, intended to be used only by Application Servers,
     not by ordinary JMS clients.
     @see javax.jms.ServerSession
  */
  public void run() {
  }
  
  public void startSession() throws JMSException {
    if (closed)
      throw 
	new javax.jms.IllegalStateException("Peforming the start operation on"
					    + " a closed Session");
    /** Need to add a hook to activate receipt of messages */
    //????????????????????????????????????????????????????
    
    stopped = false;
  }
  
  public void stopSession() throws JMSException {
    if (closed)
      throw 
	new javax.jms.IllegalStateException("Peforming the stop operation on" +
					    " a closed Session");
    /** Need to add a hook to stop the receipt of messages */
    //?????????????????????????????????????????????????????
    
    
    stopped = true;
  }
  
}
